home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Heretic Source / G_OLD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-13  |  36.8 KB  |  1,820 lines

  1.  
  2. // G_game.c
  3.  
  4. #include <string.h>
  5. #include "DoomDef.h"
  6. #include "P_local.h"
  7. #include "soundst.h"
  8.  
  9. // Macros
  10.  
  11. #define SAVE_GAME_TERMINATOR 0x1d
  12.  
  13. // Functions
  14.  
  15. boolean G_CheckDemoStatus (void);
  16. void G_ReadDemoTiccmd (ticcmd_t *cmd);
  17. void G_WriteDemoTiccmd (ticcmd_t *cmd);
  18. void G_PlayerReborn (int player);
  19. void G_InitNew (skill_t skill, int episode, int map);
  20.  
  21. void G_DoReborn (int playernum);
  22.  
  23. void G_DoLoadLevel (void);
  24. void G_DoNewGame (void);
  25. void G_DoLoadGame (void);
  26. void G_DoPlayDemo (void);
  27. void G_DoCompleted (void);
  28. void G_DoVictory (void);
  29. void G_DoWorldDone (void);
  30. void G_DoSaveGame (void);
  31.  
  32. void D_PageTicker(void);
  33. void D_AdvanceDemo(void);
  34.  
  35. struct
  36. {
  37.     mobjtype_t type;
  38.     int speed[2];
  39. } MonsterMissileInfo[] =
  40. {
  41.     { MT_IMPBALL, 10, 20 },
  42.     { MT_MUMMYFX1, 9, 18 },
  43.     { MT_KNIGHTAXE, 9, 18 },
  44.     { MT_REDAXE, 9, 18 },
  45.     { MT_BEASTBALL, 12, 20 },
  46.     { MT_WIZFX1, 18, 24 },
  47.     { MT_SNAKEPRO_A, 14, 20 },
  48.     { MT_SNAKEPRO_B, 14, 20 },
  49.     { MT_HEADFX1, 13, 20 },
  50.     { MT_HEADFX3, 10, 18 },
  51.     { MT_MNTRFX1, 20, 26 },
  52.     { MT_MNTRFX2, 14, 20 },
  53.     { MT_SRCRFX1, 20, 28 },
  54.     { MT_SOR2FX1, 20, 28 },
  55.     { -1, -1, -1 } // Terminator
  56. };
  57.  
  58. gameaction_t    gameaction;
  59. gamestate_t     gamestate;
  60. skill_t         gameskill;
  61. boolean         respawnmonsters;
  62. int             gameepisode;
  63. int             gamemap;
  64. int                 prevmap;
  65.  
  66. boolean         paused;
  67. boolean         sendpause;              // send a pause event next tic
  68. boolean         sendsave;               // send a save event next tic
  69. boolean         usergame;               // ok to save / end game
  70.  
  71. boolean         timingdemo;             // if true, exit with report on completion
  72. int             starttime;              // for comparative timing purposes      
  73.  
  74. boolean         viewactive;
  75.  
  76. boolean         deathmatch;             // only if started as net death
  77. boolean         netgame;                // only true if packets are broadcast
  78. boolean         playeringame[MAXPLAYERS];
  79. player_t        players[MAXPLAYERS];
  80.  
  81. int             consoleplayer;          // player taking events and displaying
  82. int             displayplayer;          // view being displayed
  83. int             gametic;
  84. int             levelstarttic;          // gametic at level start
  85. int             totalkills, totalitems, totalsecret;    // for intermission
  86.  
  87. char            demoname[32];
  88. boolean         demorecording;
  89. boolean         demoplayback;
  90. byte            *demobuffer, *demo_p;
  91. boolean         singledemo;             // quit after playing a demo from cmdline
  92.  
  93. boolean         precache = true;        // if true, load all graphics at start
  94.  
  95. short            consistancy[MAXPLAYERS][BACKUPTICS];
  96.  
  97. byte            *savebuffer, *save_p;
  98.  
  99.  
  100. //
  101. // controls (have defaults)
  102. //
  103. int             key_right, key_left, key_up, key_down;
  104. int             key_strafeleft, key_straferight;
  105. int             key_fire, key_use, key_strafe, key_speed;
  106. int                key_flyup, key_flydown, key_flycenter;
  107. int                key_lookup, key_lookdown, key_lookcenter;
  108. int                key_invleft, key_invright, key_useartifact;
  109.  
  110. int             mousebfire;
  111. int             mousebstrafe;
  112. int             mousebforward;
  113.  
  114. int             joybfire;
  115. int             joybstrafe;
  116. int             joybuse;
  117. int             joybspeed;
  118.  
  119.  
  120.  
  121. #define MAXPLMOVE       0x32
  122.  
  123. fixed_t         forwardmove[2] = {0x19, 0x32};
  124. fixed_t         sidemove[2] = {0x18, 0x28};
  125. fixed_t         angleturn[3] = {640, 1280, 320};     // + slow turn
  126. #define SLOWTURNTICS    6
  127.  
  128. #define NUMKEYS 256
  129. boolean         gamekeydown[NUMKEYS];
  130. int             turnheld;                   // for accelerative turning
  131. int                 lookheld;
  132.  
  133.  
  134. boolean         mousearray[4];
  135. boolean         *mousebuttons = &mousearray[1];
  136.     // allow [-1]
  137. int             mousex, mousey;             // mouse values are used once
  138. int             dclicktime, dclickstate, dclicks;
  139. int             dclicktime2, dclickstate2, dclicks2;
  140.  
  141. int             joyxmove, joyymove;         // joystick values are repeated
  142. boolean         joyarray[5];
  143. boolean         *joybuttons = &joyarray[1];     // allow [-1]
  144.  
  145. int     savegameslot;
  146. char    savedescription[32];
  147.  
  148. int inventoryTics;
  149.  
  150. #ifdef __WATCOMC__
  151. extern externdata_t *i_ExternData;
  152. #endif
  153.  
  154. //=============================================================================
  155. // Not used - ripped out for Heretic
  156. /*
  157. int G_CmdChecksum(ticcmd_t *cmd)
  158. {
  159.     int    i;
  160.     int sum;
  161.  
  162.     sum = 0;
  163.     for(i = 0; i < sizeof(*cmd)/4-1; i++)
  164.     {
  165.         sum += ((int *)cmd)[i];
  166.     }
  167.     return(sum);
  168. }
  169. */
  170.  
  171. /*
  172. ====================
  173. =
  174. = G_BuildTiccmd
  175. =
  176. = Builds a ticcmd from all of the available inputs or reads it from the
  177. = demo buffer.
  178. = If recording a demo, write it out
  179. ====================
  180. */
  181.  
  182. extern boolean inventory;
  183. extern int curpos;
  184. extern int inv_ptr;
  185.  
  186. extern  int             isCyberPresent;     // is CyberMan present?
  187. boolean usearti = true;
  188. void I_ReadCyberCmd (ticcmd_t *cmd);
  189.  
  190. void G_BuildTiccmd (ticcmd_t *cmd)
  191. {
  192.     int             i;
  193.     boolean         strafe, bstrafe;
  194.     int             speed, tspeed, lspeed;
  195.     int             forward, side;
  196.     int look, arti;
  197.     int flyheight;
  198.  
  199.     extern boolean noartiskip;
  200.  
  201. #ifdef __WATCOMC__
  202.     int angleDelta;
  203.     static int oldAngle;
  204.     extern int newViewAngleOff;
  205.     static int externInvKey;
  206.     extern boolean automapactive;
  207.     event_t ev;
  208. #endif
  209.  
  210.  
  211.     memset (cmd,0,sizeof(*cmd));
  212.     cmd->consistancy =
  213.         consistancy[consoleplayer][(maketic*ticdup)%BACKUPTICS];
  214.     if (isCyberPresent)
  215.         I_ReadCyberCmd (cmd);
  216.  
  217. //printf ("cons: %i\n",cmd->consistancy);
  218.     
  219.     strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe]
  220.         || joybuttons[joybstrafe];
  221.     speed = gamekeydown[key_speed] || joybuttons[joybspeed]
  222.         || joybuttons[joybspeed];
  223. #ifdef __WATCOMC__
  224.     if(useexterndriver)
  225.     {
  226.         speed |= (i_ExternData->buttons&EBT_SPEED);
  227.         strafe |= (i_ExternData->buttons&EBT_STRAFE);
  228.     }
  229. #endif
  230.  
  231.     forward = side = look = arti = flyheight = 0;
  232.     
  233. //
  234. // use two stage accelerative turning on the keyboard and joystick
  235. //
  236.     if (joyxmove < 0 || joyxmove > 0 
  237.     || gamekeydown[key_right] || gamekeydown[key_left])
  238.         turnheld += ticdup;
  239.     else
  240.         turnheld = 0;
  241.     if (turnheld < SLOWTURNTICS)
  242.         tspeed = 2;             // slow turn
  243.     else
  244.         tspeed = speed;
  245.  
  246.     if(gamekeydown[key_lookdown] || gamekeydown[key_lookup])
  247.     {
  248.         lookheld += ticdup;
  249.     }
  250.     else
  251.     {
  252.         lookheld = 0;
  253.     }
  254.     if(lookheld < SLOWTURNTICS)
  255.     {
  256.         lspeed = 3;
  257.     }
  258.     else
  259.     {
  260.         lspeed = 5;
  261.     }
  262.  
  263. //
  264. // let movement keys cancel each other out
  265. //
  266.     if(strafe)
  267.     {
  268.         if (gamekeydown[key_right])
  269.             side += sidemove[speed];
  270.         if (gamekeydown[key_left])
  271.             side -= sidemove[speed];
  272.         if (joyxmove > 0)
  273.             side += sidemove[speed];
  274.         if (joyxmove < 0)
  275.             side -= sidemove[speed];
  276.     }
  277.     else
  278.     {
  279.         if (gamekeydown[key_right])
  280.             cmd->angleturn -= angleturn[tspeed];
  281.         if (gamekeydown[key_left])
  282.             cmd->angleturn += angleturn[tspeed];
  283.         if (joyxmove > 0)
  284.             cmd->angleturn -= angleturn[tspeed];
  285.         if (joyxmove < 0)
  286.             cmd->angleturn += angleturn[tspeed];
  287.     }
  288.  
  289.     if (gamekeydown[key_up])
  290.         forward += forwardmove[speed];
  291.     if (gamekeydown[key_down])
  292.         forward -= forwardmove[speed];
  293.     if (joyymove < 0)
  294.         forward += forwardmove[speed];
  295.     if (joyymove > 0)
  296.         forward -= forwardmove[speed];
  297.     if (gamekeydown[key_straferight])
  298.         side += sidemove[speed];
  299.     if (gamekeydown[key_strafeleft])
  300.         side -= sidemove[speed];
  301.  
  302.     // Look up/down/center keys
  303.     if(gamekeydown[key_lookup])
  304.     {
  305.         look = lspeed;
  306.     }
  307.     if(gamekeydown[key_lookdown])
  308.     {
  309.         look = -lspeed;
  310.     }
  311.     if(gamekeydown[key_lookcenter])
  312.     {
  313.         look = TOCENTER;
  314.     }
  315.  
  316. #ifdef __WATCOMC__
  317.     if(useexterndriver && i_ExternData->buttons&EBT_CENTERVIEW)
  318.     {
  319.         look = TOCENTER;
  320.     }
  321.     if(useexterndriver && look != TOCENTER && (gamestate == GS_LEVEL ||
  322.         gamestate == GS_INTERMISSION))
  323.     {
  324.         if(i_ExternData->moveForward)
  325.         {
  326.             forward += i_ExternData->moveForward;
  327.             if(speed)
  328.             {
  329.                 forward <<= 1;
  330.             }
  331.         }
  332.         if(i_ExternData->angleTurn)
  333.         {
  334.             if(strafe)
  335.             {
  336.                 side += i_ExternData->angleTurn;
  337.             }
  338.             else
  339.             {
  340.                 cmd->angleturn += i_ExternData->angleTurn;
  341.             }
  342.         }
  343.         if(i_ExternData->moveSideways)
  344.         {
  345.             side += i_ExternData->moveSideways;
  346.             if(speed)
  347.             {
  348.                 side <<= 1;
  349.             }
  350.         }
  351.         if(i_ExternData->pitch)
  352.         {
  353.             angleDelta = i_ExternData->pitch-oldAngle;
  354.             if(abs(angleDelta < 14))
  355.             {
  356.                 look = angleDelta/2;
  357.             }
  358.             else
  359.             {
  360.                 look = 7*(angleDelta > 0 ? 1 : -1);
  361.             }
  362.             if(look == TOCENTER)
  363.             {
  364.                 look++;
  365.             }
  366.             oldAngle += look;
  367.         }
  368.         if(i_ExternData->flyDirection)
  369.         {
  370.             if(i_ExternData->flyDirection > 0)
  371.             {
  372.                 flyheight = 5;
  373.             }
  374.             else
  375.             {
  376.                 flyheight = -5;
  377.             }
  378.         }
  379.         if(abs(newViewAngleOff-i_ExternData->angleHead) < 3000)
  380.         {
  381.             newViewAngleOff = i_ExternData->angleHead;
  382.         }
  383.         if(i_ExternData->buttons&EBT_FIRE)
  384.         {
  385.             cmd->buttons |= BT_ATTACK;
  386.         }
  387.         if(i_ExternData->buttons&EBT_OPENDOOR)
  388.         {
  389.             cmd->buttons |= BT_USE;
  390.         }
  391.         if(i_ExternData->buttons&EBT_PAUSE)
  392.         {
  393.             sendpause ^= 1;
  394.         }
  395.         if(externInvKey&EBT_USEARTIFACT)
  396.         {
  397.             ev.type = ev_keyup;
  398.             ev.data1 = key_useartifact;
  399.             D_PostEvent(&ev);
  400.             externInvKey &= ~EBT_USEARTIFACT;
  401.         }
  402.         else if(i_ExternData->buttons&EBT_USEARTIFACT)
  403.         {
  404.             externInvKey |= EBT_USEARTIFACT;
  405.             ev.type = ev_keydown;
  406.             ev.data1 = key_useartifact;
  407.             D_PostEvent(&ev);
  408.         }
  409.         if(externInvKey&EBT_INVENTORYRIGHT)
  410.         {
  411.             ev.type = ev_keyup;
  412.             ev.data1 = key_invright;
  413.             D_PostEvent(&ev);
  414.             externInvKey &= ~EBT_INVENTORYRIGHT;
  415.         }
  416.         else if(i_ExternData->buttons&EBT_INVENTORYRIGHT)
  417.         {
  418.             externInvKey |= EBT_INVENTORYRIGHT;
  419.             ev.type = ev_keydown;
  420.             ev.data1 = key_invright;
  421.             D_PostEvent(&ev);
  422.         }
  423.         if(externInvKey&EBT_INVENTORYLEFT)
  424.         {
  425.             ev.type = ev_keyup;
  426.             ev.data1 = key_invleft;
  427.             D_PostEvent(&ev);
  428.             externInvKey &= ~EBT_INVENTORYLEFT;
  429.         }
  430.         else if(i_ExternData->buttons&EBT_INVENTORYLEFT)
  431.         {
  432.             externInvKey |= EBT_INVENTORYLEFT;
  433.             ev.type = ev_keydown;
  434.             ev.data1 = key_invleft;
  435.             D_PostEvent(&ev);
  436.         }
  437.         if(i_ExternData->buttons&EBT_FLYDROP)
  438.         {
  439.             flyheight = TOCENTER;
  440.         }
  441.         if(i_ExternData->buttons&EBT_MAP && gamestate == GS_LEVEL)
  442.         {
  443.             if(automapactive)
  444.             {
  445.                 AM_Stop();
  446.             }
  447.             else
  448.             {
  449.                 AM_Start();
  450.             }
  451.         }
  452.     }
  453. #endif
  454.  
  455.     // Fly up/down/drop keys
  456.     if(gamekeydown[key_flyup])
  457.     {
  458.         flyheight = 5; // note that the actual flyheight will be twice this
  459.     }
  460.     if(gamekeydown[key_flydown])
  461.     {
  462.         flyheight = -5;
  463.     }
  464.     if(gamekeydown[key_flycenter])
  465.     {
  466.         flyheight = TOCENTER;
  467.         look = TOCENTER;
  468.     }
  469.  
  470.     // Use artifact key
  471.     if(gamekeydown[key_useartifact])
  472.     {
  473.         if(gamekeydown[key_speed] && !noartiskip)
  474.         {
  475.             if(players[consoleplayer].inventory[inv_ptr].type != arti_none)
  476.             {
  477.                 gamekeydown[key_useartifact] = false;
  478.                 cmd->arti = 0xff; // skip artifact code
  479.             }
  480.         }
  481.         else
  482.         {
  483.             if(inventory)
  484.             {
  485.                 players[consoleplayer].readyArtifact =
  486.                     players[consoleplayer].inventory[inv_ptr].type;
  487.                 inventory = false;
  488.                 cmd->arti = 0;
  489.                 usearti = false;
  490.             }
  491.             else if(usearti)
  492.             {
  493.                 cmd->arti = players[consoleplayer].inventory[inv_ptr].type;
  494.                 usearti = false;
  495.             }
  496.         }
  497.     }
  498.     if(gamekeydown[127] && !cmd->arti
  499.         && !players[consoleplayer].powers[pw_weaponlevel2])
  500.     {
  501.         gamekeydown[127] = false;
  502.         cmd->arti = arti_tomeofpower;
  503.     }
  504.  
  505. //
  506. // buttons
  507. //
  508.     cmd->chatchar = CT_dequeueChatChar();
  509.  
  510.     if (gamekeydown[key_fire] || mousebuttons[mousebfire]
  511.         || joybuttons[joybfire])
  512.         cmd->buttons |= BT_ATTACK;
  513.  
  514.     if (gamekeydown[key_use] || joybuttons[joybuse] )
  515.     {
  516.         cmd->buttons |= BT_USE;
  517.         dclicks = 0;                    // clear double clicks if hit use button
  518.     }
  519.     
  520.     for(i = 0; i < NUMWEAPONS-2; i++)
  521.     {
  522.         if(gamekeydown['1'+i])
  523.         {
  524.             cmd->buttons |= BT_CHANGE;
  525.             cmd->buttons |= i<<BT_WEAPONSHIFT;
  526.             break;
  527.         }
  528.     }
  529.  
  530. //
  531. // mouse
  532. //
  533.     if (mousebuttons[mousebforward])
  534.         forward += forwardmove[speed];
  535.         
  536. //
  537. // forward double click
  538. //
  539.     if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 )
  540.     {
  541.         dclickstate = mousebuttons[mousebforward];
  542.         if (dclickstate)
  543.             dclicks++;
  544.         if (dclicks == 2)
  545.         {
  546.             cmd->buttons |= BT_USE;
  547.             dclicks = 0;
  548.         }
  549.         else
  550.             dclicktime = 0;
  551.     }
  552.     else
  553.     {
  554.         dclicktime += ticdup;
  555.         if (dclicktime > 20)
  556.         {
  557.             dclicks = 0;
  558.             dclickstate = 0;
  559.         }
  560.     }
  561.     
  562. //
  563. // strafe double click
  564. //
  565.     bstrafe = mousebuttons[mousebstrafe]
  566. || joybuttons[joybstrafe];
  567.     if (bstrafe != dclickstate2 && dclicktime2 > 1 )
  568.     {
  569.         dclickstate2 = bstrafe;
  570.         if (dclickstate2)
  571.             dclicks2++;
  572.         if (dclicks2 == 2)
  573.         {
  574.             cmd->buttons |= BT_USE;
  575.             dclicks2 = 0;
  576.         }
  577.         else
  578.             dclicktime2 = 0;
  579.     }
  580.     else
  581.     {
  582.         dclicktime2 += ticdup;
  583.         if (dclicktime2 > 20)
  584.         {
  585.             dclicks2 = 0;
  586.             dclickstate2 = 0;
  587.         }
  588.     }
  589.  
  590.     if (strafe)
  591.     {
  592.         side += mousex*2;
  593.     }
  594.     else
  595.     {
  596.         cmd->angleturn -= mousex*0x8;
  597.     }    
  598.     forward += mousey;
  599.     mousex = mousey = 0;
  600.     
  601.     if (forward > MAXPLMOVE)
  602.         forward = MAXPLMOVE;
  603.     else if (forward < -MAXPLMOVE)
  604.         forward = -MAXPLMOVE;
  605.     if (side > MAXPLMOVE)
  606.         side = MAXPLMOVE;
  607.     else if (side < -MAXPLMOVE)
  608.         side = -MAXPLMOVE;
  609.  
  610.     cmd->forwardmove += forward;
  611.     cmd->sidemove += side;
  612.     if(players[consoleplayer].playerstate == PST_LIVE)
  613.     {
  614.         if(look < 0)
  615.         {
  616.             look += 16;
  617.         }
  618.         cmd->lookfly = look;
  619.     }
  620.     if(flyheight < 0)
  621.     {
  622.         flyheight += 16;
  623.     }
  624.     cmd->lookfly |= flyheight<<4;
  625.  
  626. //
  627. // special buttons
  628. //
  629.     if (sendpause)
  630.     {
  631.         sendpause = false;
  632.         cmd->buttons = BT_SPECIAL | BTS_PAUSE;
  633.     }
  634.  
  635.     if (sendsave)
  636.     {
  637.         sendsave = false;
  638.         cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT);
  639.     }
  640. }
  641.  
  642.  
  643. /*
  644. ==============
  645. =
  646. = G_DoLoadLevel
  647. =
  648. ==============
  649. */
  650.  
  651. void G_DoLoadLevel (void)
  652. {
  653.     int             i;
  654.     
  655.     levelstarttic = gametic;        // for time calculation 
  656.     gamestate = GS_LEVEL;
  657.     for (i=0 ; i<MAXPLAYERS ; i++)
  658.     {
  659.         if (playeringame[i] && players[i].playerstate == PST_DEAD)
  660.             players[i].playerstate = PST_REBORN;
  661.         memset (players[i].frags,0,sizeof(players[i].frags));
  662.     }
  663.         
  664.     P_SetupLevel (gameepisode, gamemap, 0, gameskill);   
  665.     displayplayer = consoleplayer;      // view the guy you are playing   
  666.     starttime = I_GetTime ();
  667.     gameaction = ga_nothing;
  668.     Z_CheckHeap ();
  669.  
  670. //
  671. // clear cmd building stuff
  672. // 
  673.  
  674.     memset (gamekeydown, 0, sizeof(gamekeydown));
  675.     joyxmove = joyymove = 0;
  676.     mousex = mousey = 0;
  677.     sendpause = sendsave = paused = false;
  678.     memset (mousebuttons, 0, sizeof(mousebuttons));
  679.     memset (joybuttons, 0, sizeof(joybuttons));
  680. }
  681.  
  682.  
  683. /*
  684. ===============================================================================
  685. =
  686. = G_Responder 
  687. =
  688. = get info needed to make ticcmd_ts for the players
  689. =
  690. ===============================================================================
  691. */
  692.  
  693. boolean G_Responder(event_t *ev)
  694. {
  695.     player_t *plr;
  696.     extern boolean MenuActive;
  697.  
  698.     plr = &players[consoleplayer];
  699.     if(ev->type == ev_keyup && ev->data1 == key_useartifact)
  700.     { // flag to denote that it's okay to use an artifact
  701.         if(!inventory)
  702.         {
  703.             plr->readyArtifact = plr->inventory[inv_ptr].type;
  704.         }
  705.         usearti = true;
  706.     }
  707.  
  708.     // Check for spy mode player cycle
  709.     if(gamestate == GS_LEVEL && ev->type == ev_keydown
  710.         && ev->data1 == KEY_F12 && !deathmatch)
  711.     { // Cycle the display player
  712.         do
  713.         {
  714.             displayplayer++;
  715.             if(displayplayer == MAXPLAYERS)
  716.             {
  717.                 displayplayer = 0;
  718.             }
  719.         } while(!playeringame[displayplayer]
  720.             && displayplayer != consoleplayer);
  721.         return(true);
  722.     }
  723.  
  724.     if(gamestate == GS_LEVEL)
  725.     {
  726.         if(CT_Responder(ev))
  727.         { // Chat ate the event
  728.             return(true);
  729.         }
  730.         if(SB_Responder(ev))
  731.         { // Status bar ate the event
  732.             return(true);
  733.         }
  734.         if(AM_Responder(ev))
  735.         { // Automap ate the event
  736.             return(true);
  737.         }
  738.     }
  739.  
  740.     switch(ev->type)
  741.     {
  742.         case ev_keydown:
  743.             if(ev->data1 == key_invleft)
  744.             {
  745.                 inventoryTics = 5*35;
  746.                 if(!inventory)
  747.                 {
  748.                     inventory = true;
  749.                     break;
  750.                 }
  751.                 inv_ptr--;
  752.                 if(inv_ptr < 0)
  753.                 {
  754.                     inv_ptr = 0;
  755.                 }
  756.                 else
  757.                 {
  758.                     curpos--;
  759.                     if(curpos < 0)
  760.                     {
  761.                         curpos = 0;
  762.                     }
  763.                 }
  764.                 return(true);
  765.             }
  766.             if(ev->data1 == key_invright)
  767.             {
  768.                 inventoryTics = 5*35;
  769.                 if(!inventory)
  770.                 {
  771.                     inventory = true;
  772.                     break;
  773.                 }
  774.                 inv_ptr++;
  775.                 if(inv_ptr >= plr->inventorySlotNum)
  776.                 {
  777.                     inv_ptr--;
  778.                     if(inv_ptr < 0)
  779.                         inv_ptr = 0;
  780.                 }
  781.                 else
  782.                 {
  783.                     curpos++;
  784.                     if(curpos > 6)
  785.                     {
  786.                         curpos = 6;
  787.                     }
  788.                 }
  789.                 return(true);
  790.             }
  791.             if(ev->data1 == KEY_PAUSE && !MenuActive)
  792.             {
  793.                 sendpause = true;
  794.                 return(true);
  795.             }
  796.             if(ev->data1 < NUMKEYS)
  797.             {
  798.                 gamekeydown[ev->data1] = true;
  799.             }
  800.             return(true); // eat key down events
  801.  
  802.         case ev_keyup:
  803.             if(ev->data1 < NUMKEYS)
  804.             {
  805.                 gamekeydown[ev->data1] = false;
  806.             }
  807.             return(false); // always let key up events filter down
  808.  
  809.         case ev_mouse:
  810.             mousebuttons[0] = ev->data1&1;
  811.             mousebuttons[1] = ev->data1&2;
  812.             mousebuttons[2] = ev->data1&4;
  813.             mousex = ev->data2*(mouseSensitivity+5)/10;
  814.             mousey = ev->data3*(mouseSensitivity+5)/10;
  815.             return(true); // eat events
  816.  
  817.         case ev_joystick:
  818.             joybuttons[0] = ev->data1&1;
  819.             joybuttons[1] = ev->data1&2;
  820.             joybuttons[2] = ev->data1&4;
  821.             joybuttons[3] = ev->data1&8;
  822.             joyxmove = ev->data2;
  823.             joyymove = ev->data3;
  824.             return(true); // eat events
  825.  
  826.         default:
  827.             break;
  828.     }
  829.     return(false);
  830. }
  831.  
  832. /*
  833. ===============================================================================
  834. =
  835. = G_Ticker
  836. =
  837. ===============================================================================
  838. */
  839.  
  840. void G_Ticker (void)
  841. {
  842.     int                     i, buf;
  843.     ticcmd_t        *cmd;
  844.             
  845. //
  846. // do player reborns if needed
  847. //
  848.     for (i=0 ; i<MAXPLAYERS ; i++)
  849.         if (playeringame[i] && players[i].playerstate == PST_REBORN)
  850.             G_DoReborn (i);
  851.  
  852. //
  853. // do things to change the game state
  854. //
  855.     while (gameaction != ga_nothing)
  856.     {
  857.         switch (gameaction)
  858.         {
  859.         case ga_loadlevel:
  860.             G_DoLoadLevel ();
  861.             break;
  862.         case ga_newgame:
  863.             G_DoNewGame ();
  864.             break;
  865.         case ga_loadgame:
  866.             G_DoLoadGame ();
  867.             break;
  868.         case ga_savegame:
  869.             G_DoSaveGame ();
  870.             break;
  871.         case ga_playdemo:
  872.             G_DoPlayDemo ();
  873.             break;
  874.         case ga_screenshot:
  875.             M_ScreenShot ();
  876.             gameaction = ga_nothing;
  877.             break;
  878.         case ga_completed:
  879.             G_DoCompleted ();
  880.             break;
  881.         case ga_worlddone:
  882.             G_DoWorldDone();
  883.             break;
  884.         case ga_victory:
  885.             F_StartFinale();
  886.             break;
  887.         default:
  888.             break;
  889.         }
  890.     }
  891.     
  892.             
  893. //
  894. // get commands, check consistancy, and build new consistancy check
  895. //
  896.     buf = gametic%BACKUPTICS;
  897.  
  898.     for (i=0 ; i<MAXPLAYERS ; i++)
  899.         if (playeringame[i])
  900.         {
  901.             cmd = &players[i].cmd;
  902.  
  903.             memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t));
  904.  
  905.             if (demoplayback)
  906.                 G_ReadDemoTiccmd (cmd);
  907.             if (demorecording)
  908.                 G_WriteDemoTiccmd (cmd);
  909.  
  910.             if (netgame && !(gametic%ticdup) )
  911.             {
  912.                 if (gametic > BACKUPTICS
  913.                 && consistancy[i][buf] != cmd->consistancy)
  914.                 {
  915.                     I_Error ("consistency failure (%i should be %i)",cmd->consistancy, consistancy[i][buf]);
  916.                 }
  917.                 if (players[i].mo)
  918.                     consistancy[i][buf] = players[i].mo->x;
  919.                 else
  920.                     consistancy[i][buf] = rndindex;
  921.             }
  922.         }
  923.  
  924. //
  925. // check for special buttons
  926. //
  927.     for (i=0 ; i<MAXPLAYERS ; i++)
  928.         if (playeringame[i])
  929.         {
  930.             if (players[i].cmd.buttons & BT_SPECIAL)
  931.             {
  932.                 switch (players[i].cmd.buttons & BT_SPECIALMASK)
  933.                 {
  934.                 case BTS_PAUSE:
  935.                     paused ^= 1;
  936.                     if(paused)
  937.                     {
  938.                         S_PauseSound();
  939.                     }
  940.                     else
  941.                     {
  942.                         S_ResumeSound();
  943.                     }
  944.                     break;
  945.                     
  946.                 case BTS_SAVEGAME:
  947.                     if (!savedescription[0])
  948.                     {
  949.                         if(netgame)
  950.                         {
  951.                             strcpy (savedescription, "NET GAME");
  952.                         }
  953.                         else
  954.                         {
  955.                             strcpy(savedescription, "SAVE GAME");
  956.                         }
  957.                     }
  958.                     savegameslot = 
  959.                         (players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT;
  960.                     gameaction = ga_savegame;
  961.                     break;
  962.                 }
  963.             }
  964.         }
  965.     
  966. // turn inventory off after a certain amount of time
  967.     if(inventory && !(--inventoryTics))
  968.     {
  969.         players[consoleplayer].readyArtifact =
  970.             players[consoleplayer].inventory[inv_ptr].type;
  971.         inventory = false;
  972.         cmd->arti = 0;
  973.     }
  974. //
  975. // do main actions
  976. //
  977. //
  978. // do main actions
  979. //
  980.     switch (gamestate)
  981.     {
  982.         case GS_LEVEL:
  983.             P_Ticker ();
  984.             SB_Ticker ();
  985.             AM_Ticker ();
  986.             CT_Ticker();
  987.             break;
  988.         case GS_INTERMISSION:
  989.             IN_Ticker ();
  990.             break;
  991.         case GS_FINALE:
  992.             F_Ticker();
  993.             break;
  994.         case GS_DEMOSCREEN:
  995.             D_PageTicker ();
  996.             break;
  997.     }       
  998. }
  999.  
  1000.  
  1001. /*
  1002. ==============================================================================
  1003.  
  1004.                         PLAYER STRUCTURE FUNCTIONS
  1005.  
  1006. also see P_SpawnPlayer in P_Things
  1007. ==============================================================================
  1008. */
  1009.  
  1010. /*
  1011. ====================
  1012. =
  1013. = G_InitPlayer
  1014. =
  1015. = Called at the start
  1016. = Called by the game initialization functions
  1017. ====================
  1018. */
  1019.  
  1020. void G_InitPlayer (int player)
  1021. {
  1022.     player_t        *p;
  1023.  
  1024. // set up the saved info        
  1025.     p = &players[player];
  1026.     
  1027. // clear everything else to defaults
  1028.     G_PlayerReborn (player);
  1029.     
  1030. }
  1031.  
  1032.  
  1033. /*
  1034. ====================
  1035. =
  1036. = G_PlayerFinishLevel
  1037. =
  1038. = Can when a player completes a level
  1039. ====================
  1040. */
  1041. extern int curpos;
  1042. extern int inv_ptr;
  1043. extern int playerkeys;
  1044.  
  1045. void G_PlayerFinishLevel(int player)
  1046. {
  1047.     player_t *p;
  1048.     int i;
  1049.  
  1050. /*    // BIG HACK
  1051.     inv_ptr = 0;
  1052.     curpos = 0;
  1053. */
  1054.     // END HACK
  1055.     p = &players[player];
  1056.     for(i=0; i<p->inventorySlotNum; i++)
  1057.     {
  1058.         p->inventory[i].count = 1;
  1059.     }
  1060.     p->artifactCount = p->inventorySlotNum;
  1061.     
  1062.     if(!deathmatch)
  1063.     {
  1064.         for(i = 0; i < 16; i++)
  1065.         {
  1066.             P_PlayerUseArtifact(p, arti_fly);
  1067.         }
  1068.     }    
  1069.     memset(p->powers, 0, sizeof(p->powers));
  1070.     memset(p->keys, 0, sizeof(p->keys));
  1071.     playerkeys = 0;
  1072. //    memset(p->inventory, 0, sizeof(p->inventory));
  1073.     if(p->chickenTics)
  1074.     {
  1075.         p->readyweapon = p->mo->special1; // Restore weapon
  1076.         p->chickenTics = 0;
  1077.     }
  1078.     p->messageTics = 0;
  1079.     p->lookdir = 0;
  1080.     p->mo->flags &= ~MF_SHADOW; // Remove invisibility
  1081.     p->extralight = 0; // Remove weapon flashes
  1082.     p->fixedcolormap = 0; // Remove torch
  1083.     p->damagecount = 0; // No palette changes
  1084.     p->bonuscount = 0;
  1085.     p->rain1 = NULL;
  1086.     p->rain2 = NULL;
  1087.     if(p == &players[consoleplayer])
  1088.     {
  1089.         SB_state = -1; // refresh the status bar
  1090.     }
  1091. }
  1092.  
  1093. /*
  1094. ====================
  1095. =
  1096. = G_PlayerReborn
  1097. =
  1098. = Called after a player dies
  1099. = almost everything is cleared and initialized
  1100. ====================
  1101. */
  1102.  
  1103. void G_PlayerReborn(int player)
  1104. {
  1105.     player_t *p;
  1106.     int i;
  1107.     int frags[MAXPLAYERS];
  1108.     int killcount, itemcount, secretcount;
  1109.     boolean secret;
  1110.     
  1111.     secret = false;
  1112.     memcpy(frags, players[player].frags, sizeof(frags));
  1113.     killcount = players[player].killcount;
  1114.     itemcount = players[player].itemcount;
  1115.     secretcount = players[player].secretcount;
  1116.  
  1117.     p = &players[player];
  1118.     if(p->didsecret)
  1119.     {
  1120.         secret = true;
  1121.     }
  1122.     memset(p, 0, sizeof(*p));
  1123.  
  1124.     memcpy(players[player].frags, frags, sizeof(players[player].frags));
  1125.     players[player].killcount = killcount;
  1126.     players[player].itemcount = itemcount;
  1127.     players[player].secretcount = secretcount;
  1128.  
  1129.     p->usedown = p->attackdown = true; // don't do anything immediately
  1130.     p->playerstate = PST_LIVE;
  1131.     p->health = MAXHEALTH;
  1132.     p->readyweapon = p->pendingweapon = wp_goldwand;
  1133.     p->weaponowned[wp_staff] = true;
  1134.     p->weaponowned[wp_goldwand] = true;
  1135.     p->messageTics = 0;
  1136.     p->lookdir = 0;
  1137.     p->ammo[am_goldwand] = 50;
  1138.     for(i = 0; i < NUMAMMO; i++)
  1139.     {
  1140.         p->maxammo[i] = maxammo[i];
  1141.     }
  1142.     if(gamemap == 9 || secret)
  1143.     {
  1144.         p->didsecret = true;
  1145.     }
  1146.     if(p == &players[consoleplayer])
  1147.     {
  1148.         SB_state = -1; // refresh the status bar
  1149.     }
  1150. }
  1151.  
  1152. /*
  1153. ====================
  1154. =
  1155. = G_CheckSpot 
  1156. =
  1157. = Returns false if the player cannot be respawned at the given mapthing_t spot 
  1158. = because something is occupying it
  1159. ====================
  1160. */
  1161.  
  1162. void P_SpawnPlayer (mapthing_t *mthing);
  1163.  
  1164. boolean G_CheckSpot (int playernum, mapthing_t *mthing)
  1165. {
  1166.     fixed_t         x,y;
  1167.     subsector_t *ss;
  1168.     unsigned        an;
  1169.     mobj_t      *mo;
  1170.     
  1171.     x = mthing->x << FRACBITS;
  1172.     y = mthing->y << FRACBITS;
  1173.  
  1174.     players[playernum].mo->flags2 &= ~MF2_PASSMOBJ;
  1175.     if (!P_CheckPosition (players[playernum].mo, x, y) )
  1176.     {
  1177.         players[playernum].mo->flags2 |= MF2_PASSMOBJ;
  1178.         return false;
  1179.     }
  1180.     players[playernum].mo->flags2 |= MF2_PASSMOBJ;
  1181.  
  1182. // spawn a teleport fog
  1183.     ss = R_PointInSubsector (x,y);
  1184.     an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT;
  1185.  
  1186.     mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an]
  1187.     , ss->sector->floorheight+TELEFOGHEIGHT
  1188. , MT_TFOG);
  1189.     
  1190.     if (players[consoleplayer].viewz != 1)
  1191.         S_StartSound (mo, sfx_telept);  // don't start sound on first frame
  1192.  
  1193.     return true;
  1194. }
  1195.  
  1196. /*
  1197. ====================
  1198. =
  1199. = G_DeathMatchSpawnPlayer
  1200. =
  1201. = Spawns a player at one of the random death match spots
  1202. = called at level load and each death
  1203. ====================
  1204. */
  1205.  
  1206. void G_DeathMatchSpawnPlayer (int playernum)
  1207. {
  1208.     int             i,j;
  1209.     int             selections;
  1210.     
  1211.     selections = deathmatch_p - deathmatchstarts;
  1212.     if (selections < 4)
  1213.         I_Error ("Only %i deathmatch spots, 4 required", selections);
  1214.  
  1215.     for (j=0 ; j<20 ; j++)
  1216.     {
  1217.         i = P_Random() % selections;
  1218.         if (G_CheckSpot (playernum, &deathmatchstarts[i]) )
  1219.         {
  1220.             deathmatchstarts[i].type = playernum+1;
  1221.             P_SpawnPlayer (&deathmatchstarts[i]);
  1222.             return;
  1223.         }
  1224.     }
  1225.  
  1226. // no good spot, so the player will probably get stuck
  1227.     P_SpawnPlayer (&playerstarts[playernum]);
  1228. }
  1229.  
  1230. /*
  1231. ====================
  1232. =
  1233. = G_DoReborn
  1234. =
  1235. ====================
  1236. */
  1237.  
  1238. void G_DoReborn (int playernum)
  1239. {
  1240.     int                             i;
  1241.     
  1242.     if (G_CheckDemoStatus ())
  1243.         return;
  1244.     if (!netgame)
  1245.         gameaction = ga_loadlevel;                      // reload the level from scratch
  1246.     else
  1247.     {       // respawn at the start
  1248.         players[playernum].mo->player = NULL;   // dissasociate the corpse
  1249.         
  1250.         // spawn at random spot if in death match
  1251.         if (deathmatch)
  1252.         {
  1253.             G_DeathMatchSpawnPlayer (playernum);
  1254.             return;
  1255.         }
  1256.         
  1257.         if (G_CheckSpot (playernum, &playerstarts[playernum]) )
  1258.         {
  1259.             P_SpawnPlayer (&playerstarts[playernum]);
  1260.             return;
  1261.         }
  1262.         // try to spawn at one of the other players spots
  1263.         for (i=0 ; i<MAXPLAYERS ; i++)
  1264.             if (G_CheckSpot (playernum, &playerstarts[i]) )
  1265.             {
  1266.                 playerstarts[i].type = playernum+1;             // fake as other player
  1267.                 P_SpawnPlayer (&playerstarts[i]);
  1268.                 playerstarts[i].type = i+1;                             // restore
  1269.                 return;
  1270.             }
  1271.         // he's going to be inside something.  Too bad.
  1272.         P_SpawnPlayer (&playerstarts[playernum]);
  1273.     }
  1274. }
  1275.  
  1276.  
  1277. void G_ScreenShot (void)
  1278. {
  1279.     gameaction = ga_screenshot;
  1280. }
  1281.  
  1282.  
  1283. /*
  1284. ====================
  1285. =
  1286. = G_DoCompleted
  1287. =
  1288. ====================
  1289. */
  1290.  
  1291. boolean         secretexit;
  1292.  
  1293. void G_ExitLevel (void)
  1294. {
  1295.     secretexit = false;
  1296.     gameaction = ga_completed;
  1297. }
  1298.  
  1299. void G_SecretExitLevel (void)
  1300. {
  1301.     secretexit = true;
  1302.     gameaction = ga_completed;
  1303. }
  1304.  
  1305. void G_DoCompleted(void)
  1306. {
  1307.     int i;
  1308.     static int afterSecret[3] = { 7, 5, 5 };
  1309.  
  1310.     gameaction = ga_nothing;
  1311.     if(G_CheckDemoStatus())
  1312.     {
  1313.         return;
  1314.     }
  1315.     for(i = 0; i < MAXPLAYERS; i++)
  1316.     {
  1317.         if(playeringame[i])
  1318.         {
  1319.             G_PlayerFinishLevel(i);
  1320.         }
  1321.     }
  1322.     prevmap = gamemap;
  1323.     if(secretexit == true)
  1324.     {
  1325.         gamemap = 9;
  1326.     }
  1327.     else if(gamemap == 9)
  1328.     { // Finished secret level
  1329.         gamemap = afterSecret[gameepisode-1];
  1330.     }
  1331.     else if(gamemap == 8)
  1332.     {
  1333.         gameaction = ga_victory;
  1334.         return;
  1335.     }
  1336.     else
  1337.     {
  1338.         gamemap++;
  1339.     }
  1340.     gamestate = GS_INTERMISSION;
  1341.     IN_Start();
  1342. }
  1343.  
  1344. //============================================================================
  1345. //
  1346. // G_WorldDone
  1347. //
  1348. //============================================================================
  1349.  
  1350. void G_WorldDone(void)
  1351. {
  1352.     gameaction = ga_worlddone;
  1353. }
  1354.  
  1355. //============================================================================
  1356. //
  1357. // G_DoWorldDone
  1358. //
  1359. //============================================================================
  1360.  
  1361. void G_DoWorldDone(void)
  1362. {
  1363.     gamestate = GS_LEVEL;
  1364.     G_DoLoadLevel();
  1365.     gameaction = ga_nothing;
  1366.     viewactive = true;
  1367. }
  1368.  
  1369. //---------------------------------------------------------------------------
  1370. //
  1371. // PROC G_LoadGame
  1372. //
  1373. // Can be called by the startup code or the menu task.
  1374. //
  1375. //---------------------------------------------------------------------------
  1376.  
  1377. char savename[256];
  1378.  
  1379. void G_LoadGame(char *name)
  1380. {
  1381.     strcpy(savename, name);
  1382.     gameaction = ga_loadgame;
  1383. }
  1384.  
  1385. //---------------------------------------------------------------------------
  1386. //
  1387. // PROC G_DoLoadGame
  1388. //
  1389. // Called by G_Ticker based on gameaction.
  1390. //
  1391. //---------------------------------------------------------------------------
  1392.  
  1393. #define VERSIONSIZE 16
  1394.  
  1395. void G_DoLoadGame(void)
  1396. {
  1397.     int length;
  1398.     int i;
  1399.     int a, b, c;
  1400.     char vcheck[VERSIONSIZE];
  1401.  
  1402.     gameaction = ga_nothing;
  1403.  
  1404.     length = M_ReadFile(savename, &savebuffer);
  1405.     save_p = savebuffer+SAVESTRINGSIZE;
  1406.     // Skip the description field
  1407.     memset(vcheck, 0, sizeof(vcheck));
  1408.     sprintf(vcheck, "version %i", VERSION);
  1409.     if (strcmp (save_p, vcheck))
  1410.     { // Bad version
  1411.         return;
  1412.     }
  1413.     save_p += VERSIONSIZE;
  1414.     gameskill = *save_p++;
  1415.     gameepisode = *save_p++;
  1416.     gamemap = *save_p++;
  1417.     for(i = 0; i < MAXPLAYERS; i++)
  1418.     {
  1419.         playeringame[i] = *save_p++;
  1420.     }
  1421.     // Load a base level
  1422.     G_InitNew(gameskill, gameepisode, gamemap);
  1423.  
  1424.     // Create leveltime
  1425.     a = *save_p++;
  1426.     b = *save_p++;
  1427.     c = *save_p++;
  1428.     leveltime = (a<<16)+(b<<8)+c;
  1429.  
  1430.     // De-archive all the modifications
  1431.     P_UnArchivePlayers();
  1432.     P_UnArchiveWorld();
  1433.     P_UnArchiveThinkers();
  1434.     P_UnArchiveSpecials();
  1435.  
  1436.     if(*save_p != SAVE_GAME_TERMINATOR)
  1437.     { // Missing savegame termination marker
  1438.         I_Error("Bad savegame");
  1439.     }
  1440.     Z_Free(savebuffer);
  1441. }
  1442.  
  1443. //---------------------------------------------------------------------------
  1444. //
  1445. // PROC G_SaveGame
  1446. //
  1447. // Called by the menu task.  <description> is a 24 byte text string.
  1448. //
  1449. //---------------------------------------------------------------------------
  1450.  
  1451. void G_SaveGame(int slot, char *description)
  1452. {
  1453.     savegameslot = slot;
  1454.     strcpy(savedescription, description);
  1455.     sendsave = true;
  1456. }
  1457.  
  1458. //---------------------------------------------------------------------------
  1459. //
  1460. // PROC G_DoSaveGame
  1461. //
  1462. // Called by G_Ticker based on gameaction.
  1463. //
  1464. //---------------------------------------------------------------------------
  1465.  
  1466. void G_DoSaveGame(void)
  1467. {
  1468.     char name[100];
  1469.     char name2[VERSIONSIZE];
  1470.     char *description;
  1471.     int length;
  1472.     int i;
  1473.  
  1474.     if(cdrom)
  1475.     {
  1476.         sprintf(name, SAVEGAMENAMECD"%d.hsg", savegameslot);
  1477.     }
  1478.     else
  1479.     {
  1480.         sprintf(name, SAVEGAMENAME"%d.hsg", savegameslot);
  1481.     }
  1482.     description = savedescription;
  1483.  
  1484.     // Allocate save game buffer
  1485.     save_p = savebuffer = Z_Malloc(SAVEGAMESIZE, PU_STATIC, NULL);
  1486.  
  1487.     memcpy(save_p, description, SAVESTRINGSIZE);
  1488.     save_p += SAVESTRINGSIZE;
  1489.     memset(name2, 0, sizeof(name2));
  1490.     sprintf(name2, "version %i",VERSION);
  1491.     memcpy(save_p, name2, VERSIONSIZE);
  1492.     save_p += VERSIONSIZE;
  1493.  
  1494.     *save_p++ = gameskill;
  1495.     *save_p++ = gameepisode;
  1496.     *save_p++ = gamemap;
  1497.     for(i = 0; i < MAXPLAYERS; i++)
  1498.     {
  1499.         *save_p++ = playeringame[i];
  1500.     }
  1501.     *save_p++ = leveltime>>16;
  1502.     *save_p++ = leveltime>>8;
  1503.     *save_p++ = leveltime;
  1504.  
  1505.     P_ArchivePlayers();
  1506.     P_ArchiveWorld();
  1507.     P_ArchiveThinkers();
  1508.     P_ArchiveSpecials();
  1509.  
  1510.     // Send a savegame termination marker
  1511.     *save_p++ = SAVE_GAME_TERMINATOR;
  1512.  
  1513.     length = save_p-savebuffer;
  1514.     if(length > SAVEGAMESIZE)
  1515.     {
  1516.         I_Error("Savegame buffer overrun");
  1517.     }
  1518.     M_WriteFile(name, savebuffer, length);
  1519.     gameaction = ga_nothing;
  1520.     savedescription[0] = 0;
  1521.     Z_Free(savebuffer);
  1522.     P_SetMessage(&players[consoleplayer], TXT_GAMESAVED, true);
  1523. }
  1524.  
  1525. /*
  1526. ====================
  1527. =
  1528. = G_InitNew
  1529. =
  1530. = Can be called by the startup code or the menu task
  1531. = consoleplayer, displayplayer, playeringame[] should be set
  1532. ====================
  1533. */
  1534.  
  1535. skill_t d_skill;
  1536. int     d_episode;
  1537. int     d_map;
  1538.  
  1539. void G_DeferedInitNew (skill_t skill, int episode, int map)
  1540. {
  1541.     d_skill = skill;
  1542.     d_episode = episode;
  1543.     d_map = map;
  1544.     gameaction = ga_newgame;
  1545. }
  1546.  
  1547. void G_DoNewGame (void)
  1548. {
  1549.     G_InitNew (d_skill, d_episode, d_map);
  1550.     gameaction = ga_nothing;
  1551. }
  1552.  
  1553. extern  int                     skytexture;
  1554.  
  1555. void G_InitNew(skill_t skill, int episode, int map)
  1556. {
  1557.     int i;
  1558.     int speed;
  1559.  
  1560.     if(paused)
  1561.     {
  1562.         paused = false;
  1563.         S_ResumeSound();
  1564.     }
  1565.     if(skill < sk_baby)
  1566.         skill = sk_baby;
  1567.     if(skill > sk_nightmare)
  1568.         skill = sk_nightmare;
  1569.     if(episode < 1)
  1570.         episode = 1;
  1571.     // Up to 9 episodes for testing
  1572.     if(episode > 9)
  1573.         episode = 9;
  1574.     if(map < 1)
  1575.         map = 1;
  1576.     if(map > 9)
  1577.         map = 9;
  1578.     M_ClearRandom();
  1579.     if(respawnparm)
  1580.     {
  1581.         respawnmonsters = true;
  1582.     }
  1583.     else
  1584.     {
  1585.         respawnmonsters = false;
  1586.     }
  1587.     // Set monster missile speeds
  1588.     speed = skill == sk_nightmare;
  1589.     for(i = 0; MonsterMissileInfo[i].type != -1; i++)
  1590.     {
  1591.         mobjinfo[MonsterMissileInfo[i].type].speed
  1592.             = MonsterMissileInfo[i].speed[speed]<<FRACBITS;
  1593.     }
  1594.     // Force players to be initialized upon first level load
  1595.     for(i = 0; i < MAXPLAYERS; i++)
  1596.     {
  1597.         players[i].playerstate = PST_REBORN;
  1598.     }
  1599.     // Set up a bunch of globals
  1600.     usergame = true; // will be set false if a demo
  1601.     paused = false;
  1602.     demorecording = false;
  1603.     demoplayback = false;
  1604.     viewactive = true;
  1605.     gameepisode = episode;
  1606.     gamemap = map;
  1607.     gameskill = skill;
  1608.     viewactive = true;
  1609.     BorderNeedRefresh = true;
  1610.  
  1611.     // Set the sky map
  1612.     switch(episode)
  1613.     {
  1614.         case 1:
  1615.             skytexture = R_TextureNumForName("SKY1");
  1616.             break;
  1617.         case 2:
  1618.             skytexture = R_TextureNumForName("SKY2");
  1619.             break;
  1620.         case 3:
  1621.             skytexture = R_TextureNumForName("SKY3");
  1622.             break;
  1623.         default:
  1624.             skytexture = R_TextureNumForName("SKY1");
  1625.             break;
  1626.     }
  1627.  
  1628. //
  1629. // give one null ticcmd_t
  1630. //
  1631. #if 0
  1632.     gametic = 0;
  1633.     maketic = 1;
  1634.     for (i=0 ; i<MAXPLAYERS ; i++)
  1635.         nettics[i] = 1;                 // one null event for this gametic
  1636.     memset (localcmds,0,sizeof(localcmds));
  1637.     memset (netcmds,0,sizeof(netcmds));
  1638. #endif
  1639.     G_DoLoadLevel();
  1640. }
  1641.  
  1642.  
  1643. /*
  1644. ===============================================================================
  1645.  
  1646.                             DEMO RECORDING
  1647.  
  1648. ===============================================================================
  1649. */
  1650.  
  1651. #define DEMOMARKER      0x80
  1652.  
  1653. void G_ReadDemoTiccmd (ticcmd_t *cmd)
  1654. {
  1655.     if (*demo_p == DEMOMARKER)
  1656.     {       // end of demo data stream
  1657.         G_CheckDemoStatus ();
  1658.         return;
  1659.     }
  1660.     cmd->forwardmove = ((signed char)*demo_p++);
  1661.     cmd->sidemove = ((signed char)*demo_p++);
  1662.     cmd->angleturn = ((unsigned char)*demo_p++)<<8;
  1663.     cmd->buttons = (unsigned char)*demo_p++;
  1664.     cmd->lookfly = (unsigned char)*demo_p++;
  1665.     cmd->arti = (unsigned char)*demo_p++;
  1666. }
  1667.  
  1668. void G_WriteDemoTiccmd (ticcmd_t *cmd)
  1669. {
  1670.     if (gamekeydown['q'])           // press q to end demo recording
  1671.         G_CheckDemoStatus ();
  1672.     *demo_p++ = cmd->forwardmove;
  1673.     *demo_p++ = cmd->sidemove;
  1674.     *demo_p++ = cmd->angleturn>>8;
  1675.     *demo_p++ = cmd->buttons;
  1676.     *demo_p++ = cmd->lookfly;
  1677.     *demo_p++ = cmd->arti;
  1678.     demo_p -= 6;
  1679.     G_ReadDemoTiccmd (cmd);         // make SURE it is exactly the same
  1680. }
  1681.  
  1682.  
  1683.  
  1684. /*
  1685. ===================
  1686. =
  1687. = G_RecordDemo
  1688. =
  1689. ===================
  1690. */
  1691.  
  1692. void G_RecordDemo (skill_t skill, int numplayers, int episode, int map, char *name)
  1693. {
  1694.     int             i;
  1695.     
  1696.     G_InitNew (skill, episode, map);
  1697.     usergame = false;
  1698.     strcpy (demoname, name);
  1699.     strcat (demoname, ".lmp");
  1700.     demobuffer = demo_p = Z_Malloc (0x20000,PU_STATIC,NULL);
  1701.     *demo_p++ = skill;
  1702.     *demo_p++ = episode;
  1703.     *demo_p++ = map;
  1704.     
  1705.     for (i=0 ; i<MAXPLAYERS ; i++)
  1706.         *demo_p++ = playeringame[i];
  1707.         
  1708.     demorecording = true;
  1709. }
  1710.  
  1711.  
  1712. /*
  1713. ===================
  1714. =
  1715. = G_PlayDemo
  1716. =
  1717. ===================
  1718. */
  1719.  
  1720. char    *defdemoname;
  1721.  
  1722. void G_DeferedPlayDemo (char *name)
  1723. {
  1724.     defdemoname = name;
  1725.     gameaction = ga_playdemo;
  1726. }
  1727.  
  1728. void G_DoPlayDemo (void)
  1729. {
  1730.     skill_t skill;
  1731.     int             i, episode, map;
  1732.     
  1733.     gameaction = ga_nothing;
  1734.     demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC);
  1735.     skill = *demo_p++;
  1736.     episode = *demo_p++;
  1737.     map = *demo_p++;
  1738.  
  1739.     for (i=0 ; i<MAXPLAYERS ; i++)
  1740.         playeringame[i] = *demo_p++;
  1741.         
  1742.     precache = false;               // don't spend a lot of time in loadlevel
  1743.     G_InitNew (skill, episode, map);
  1744.     precache = true;
  1745.     usergame = false;
  1746.     demoplayback = true;
  1747. }
  1748.  
  1749.  
  1750. /*
  1751. ===================
  1752. =
  1753. = G_TimeDemo
  1754. =
  1755. ===================
  1756. */
  1757.  
  1758. void G_TimeDemo (char *name)
  1759. {
  1760.     skill_t skill;
  1761.     int             episode, map;
  1762.     
  1763.     demobuffer = demo_p = W_CacheLumpName (name, PU_STATIC);
  1764.     skill = *demo_p++;
  1765.     episode = *demo_p++;
  1766.     map = *demo_p++;
  1767.     G_InitNew (skill, episode, map);
  1768.     usergame = false;
  1769.     demoplayback = true;
  1770.     timingdemo = true;
  1771.     singletics = true;
  1772. }
  1773.  
  1774.  
  1775. /*
  1776. ===================
  1777. =
  1778. = G_CheckDemoStatus
  1779. =
  1780. = Called after a death or level completion to allow demos to be cleaned up
  1781. = Returns true if a new demo loop action will take place
  1782. ===================
  1783. */
  1784.  
  1785. boolean G_CheckDemoStatus (void)
  1786. {
  1787.     int             endtime;
  1788.     
  1789.     if (timingdemo)
  1790.     {
  1791.         endtime = I_GetTime ();
  1792.         I_Error ("timed %i gametics in %i realtics",gametic
  1793.         , endtime-starttime);
  1794.     }
  1795.     
  1796.     if (demoplayback)
  1797.     {
  1798.         if (singledemo)
  1799.             I_Quit ();
  1800.             
  1801.         Z_ChangeTag (demobuffer, PU_CACHE);
  1802.         demoplayback = false;
  1803.         D_AdvanceDemo ();
  1804.         return true;
  1805.     }
  1806.  
  1807.     if (demorecording)
  1808.     {
  1809.         *demo_p++ = DEMOMARKER;
  1810.         M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
  1811.         Z_Free (demobuffer);
  1812.         demorecording = false;
  1813.         I_Error ("Demo %s recorded",demoname);
  1814.     }
  1815.     
  1816.     return false;
  1817. }
  1818.  
  1819.  
  1820.  
  1821.